// src/utils/ModelManager.js
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import colorControl from "@/utils/colorControl.js";
import visibilityControl from "@/utils/visibilityControl.js";

export class ModelManager {
  constructor(scene) {
    this.scene = scene;
    this.model = null;
    this.partNames = [];
    this.predefinedPartColors = {
      主油枕: colorControl.colors.yellow,
      高压绕组: colorControl.colors.red,
      低压套管: colorControl.colors.green,
      铁芯: colorControl.colors.blue,
      冷却系统: colorControl.colors.orange,
    };
    this.predefinedHiddenParts = ["外壳", "防护罩", "盖板"];
  }

  async loadModel(modelPath) {
    const loader = new GLTFLoader();

    try {
      const gltf = await loader.loadAsync(modelPath);
      this.model = gltf.scene;
      // console.log("模型加载成功:", this.model);

      // 自动调整模型大小和位置
      const box = new THREE.Box3().setFromObject(this.model);
      const center = box.getCenter(new THREE.Vector3());
      const size = box.getSize(new THREE.Vector3());

      const maxDim = Math.max(size.x, size.y, size.z);
      const scale = 2.5 / maxDim;

      this.model.scale.set(scale, scale, scale);
      this.model.position.sub(center.multiplyScalar(scale));

      this.scene.add(this.model);

      // 提取模型部件名称
      this.extractModelPartNames();

      // 如果模型有动画，播放动画
      if (gltf.animations?.length) {
        const mixer = new THREE.AnimationMixer(this.model);
        const animation = mixer.clipAction(gltf.animations[0]);
        animation.play();

        const updateAnimation = () => {
          mixer.update(0.01);
          requestAnimationFrame(updateAnimation);
        };
        updateAnimation();
      }

      // 自动高亮部件和隐藏油箱
      setTimeout(() => {
        this.highlightMultipleParts();
        visibilityControl.hidePart(this.model, "油箱");
      }, 100);

      return this.model;
    } catch (error) {
      console.error("模型加载失败:", error);
      return null;
    }
  }

  extractModelPartNames() {
    this.partNames = [];

    // console.log("=== 模型部件列表 ===");
    this.model.traverse((child) => {
      if (child.isMesh && child.name) {
        this.partNames.push(child.name);
        console.log(child.name);
      }
    });
    // console.log("==================");

    // console.log("=== 匹配的零部件信息 ===");
    this.partNames.forEach((partName) => {
      const matchedPart = Object.keys(this.predefinedPartColors).find((name) =>
        partName.toLowerCase().includes(name.toLowerCase())
      );

      if (matchedPart) {
        console.log(`${partName} -> 匹配到: ${matchedPart}`);
      } else {
        console.log(`${partName} -> 未匹配到零部件参数`);
      }
    });
    console.log("========================");
  }

  highlightPart(partName) {
    const color = this.predefinedPartColors[partName] || colorControl.colors.yellow;
    colorControl.changePartColor(this.model, partName, color);
  }

  highlightMultipleParts() {
    colorControl.changeMultiplePartsColor(this.model, this.predefinedPartColors);
  }

  restoreAllColors() {
    colorControl.restoreAllPartsColor(this.model);
  }

  hideInternalStructureObstacles() {
    visibilityControl.hideMultipleParts(this.model, this.predefinedHiddenParts);
  }

  showAllInternalStructure() {
    visibilityControl.showAllParts(this.model);
  }

  toggleInternalStructureView() {
    let hasHiddenParts = false;
    if (!this.model) return;

    this.model.traverse((child) => {
      if (child.isMesh && child.name) {
        this.predefinedHiddenParts.forEach((partName) => {
          if (child.name.toLowerCase().includes(partName.toLowerCase())) {
            if (
              !child.visible ||
              (visibilityControl.partStates.has(child.uuid) &&
                !visibilityControl.partStates.get(child.uuid).currentlyVisible)
            ) {
              hasHiddenParts = true;
            }
          }
        });
      }
    });

    if (hasHiddenParts) {
      this.showAllInternalStructure();
    } else {
      this.hideInternalStructureObstacles();
    }
  }

  getModel() {
    return this.model;
  }

  getPartNames() {
    return this.partNames;
  }

  dispose() {
    colorControl.restoreAllPartsColor(this.model);
    visibilityControl.restoreAllPartsVisibility(this.model);
  }
}